# 面向对象编程

# 创建类
class Person: # 定义一个名为Person的类, 用于表示一个人的信息
    def __init__(self, name, age): # 定义一个名为__init__的方法, 用于初始化对象的属性
        self.name = name # 将name属性赋值为name参数的值
        self.age = age # 将age属性赋值为age参数的值
    def say_hello(self): # 定义一个名为say_hello的方法, 用于打印问候语
        print("Hello, my name is {}, I\'m {}".format(self.name, self.age)) # 打印问候语, 包含name属性的值
    def get_age(self): # 定义一个名为get_age的方法, 用于返回age属性的值
        return self.age # 返回age属性的值

# 创建对象
p = Person("Alice", "30") # 创建一个名为p的对象, 类型为Person, 并传入参数"Alice"和30
p.say_hello() # 调用p对象的say_hello方法, 输出: Hello, my name is Alice,I'm 30
print(p.get_age()) # 调用p对象的get_age方法, 输出: 30


# 继承
class Student(Person): # 定义一个名为Student的类, 继承自Person类
    def __init__(self, name, age, school): # 定义一个名为__init__的方法, 用于初始化对象的属性
        super().__init__(name, age) # 继承首选 调用父类的__init__方法, 传入参数name和age
        # Person.__init__(self, name, age) # 继承同上 调用父类的__init__方法, 传入参数name和age

        self.school = school # 将school属性赋值为school参数的值
    def say_hello(self): # 定义一个名为say_hello的方法, 用于打印问候语
        print("Hello, my name is {}, I\'m {}, I\'m in {}".format(self.name, self.age, self.school)) # 打印问候语, 包含name属性的值和school属性的值
    def get_school(self): # 定义一个名为get_school的方法, 用于返回school属性的值
        return self.school # 返回school属性的值

# 创建对象
s = Student("Bob", "18", "School of Computer Science") # 创建一个名为s的对象, 类型为Student, 并传入参数"Bob", 18和"School of Computer Science"
s.say_hello() # 调用s对象的say_hello方法, 输出: Hello, my name is Bob,I'm 18, I'm in School of Computer Science
print(s.get_school()) # 调用s对象的get_school方法, 输出: School of Computer Science

# 是否继承: 内置函数isinstance()，issubclass()用于检查继承.
print(isinstance(s, Student)) # 返回True, 因为s是Student类的实例
print(isinstance(s, Person)) # 返回True, 因为s是Person类的实例
print(issubclass(Student, Person)) # 返回True, 因为Student类是Person类的子类
print(issubclass(Person, Student)) # 返回False, 因为Person类不是Student类的子类

class Parrot:
    # 类属性
    species = "鸟"
    # 示例属性
    def __init__(self, name, age):
        self.name = name
        self.age = age
# 示例化Parrot类
blu = Parrot("麻雀", 10)
woo = Parrot("鹦鹉", 15)

# 访问类属性
print("麻雀是 {}".format(blu.__class__.species))
print("鹦鹉也是 {}".format(woo.__class__.species))

# 访问示例属性
print("{} 有 {} 岁".format( blu.name, blu.age))
print("{} 有 {} 岁".format( woo.name, woo.age))


# 类的 私有属性在类的外部无法直接访问, 但可以通过公共方法来访问和修改。
class Computer:

    def __init__(self):
        self.__maxprice = 900

    def sell(self):
        print("售价: {}".format(self.__maxprice))

    def setMaxPrice(self, price):
        self.__maxprice = price

c = Computer()
c.sell()

# 改变价格
c.__maxprice = 1000
c.sell()

# 使用setter函数
c.setMaxPrice(1000)
c.sell()


# 多态性,接口
class Parrot:

    def fly(self):
        print("鹦鹉会飞")
    
    def swim(self):
        print("鹦鹉不会游泳")

class Penguin:

    def fly(self):
        print("企鹅不会飞")
    
    def swim(self):
        print("企鹅会游泳")

# 通用接口, 接受任何对象, 只要它实现了fly()方法,就能统一调用同一个方法。
def flying_test(bird):
    bird.fly()

#示例化对象
blu = Parrot()
peggy = Penguin()

# 传递对象
flying_test(blu)
flying_test(peggy)

# 可以用del 删除对象，或对象的属性，或对象的方法，或整个类。

# 多重继承,object是所有类的基类,如果一个类没有继承任何类,则默认继承object类。
# 多继承的方法解析顺序(MRO)是从左到右,从下到上的顺序。
class Base1:
    pass
class Base2:
    pass
class MultiDerived(Base1, Base2):
    pass

print(MultiDerived.__mro__) # 输出: (<class '__main__.MultiDerived'>, <class '__main__.Base1'>, <class '__main__.Base2'>, <class 'object'>)
print(MultiDerived.mro()) # 输出: [<class '__main__.MultiDerived'>, <class '__main__.Base1'>, <class '__main__.Base2'>, <class 'object'>]


# 总结： 
# 1. 类是创建对象的蓝图，对象是类的实例。
# 2. 类定义了对象的属性和方法。
# 3. 类属性是所有实例共享的属性，而实例属性是每个实例独有的属性。
# 4. 类方法是类的函数，而实例方法是类的实例的函数。
# 5. 多态性是指不同类的对象可以共享相同的方法名，并且可以根据对象的类型调用不同的方法。
# 6. 封装是指将数据和方法组合在一个类中，隐藏了类的实现细节，只暴露必要的接口。
# 7. 继承是指一个类可以继承另一个类的属性和方法，并且可以添加自己的属性和方法。
# 8. 组合是指一个类可以包含其他类的对象作为自己的属性。
# 9. 抽象是指将复杂的问题分解为简单的问题，并且只暴露必要的接口。
# 10. 接口是指一个类的方法，其他类可以实现这个方法。


# 特殊函数
# 用于操作类的实例。使用特殊函数，我们可以使我们的类与内置函数兼容
# __init__()方法用于初始化对象的属性。

# 重载运算符
# 用于操作类的实例。使用重载运算符，我们可以使我们的类与内置运算符兼容。
# __add__()方法用于重载+运算符。
class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)
    def __add__(self,other):
        return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2) # 输出: Vector (7, 8)

